//    Copyright (C) Kherty.  All rights reserved.
#region

using System.Collections.Generic;
using System.Diagnostics.Contracts;
using OpenLS.Core.Serialization;
using OpenLS.Vml.Serialization;

#endregion

namespace OpenLS.Vml
{
    public class Shape : IOfficeXmlSerializable
    {
        internal const string xmlName = "shape";
        private readonly List<ShapeElement> _elements = new List<ShapeElement>();
        private string _adj;
        private AllCoreAttributes _core;
        private string _equationxml;

        private string _gfxdata;
        private string _path;
        private AllShapeAttributes _shape;
        private ShapeType _type;

        public string gfxdata
        {
            get { return _gfxdata; }
            set { _gfxdata = value; }
        }


        public string EquationXml
        {
            get { return _equationxml; }
            set { _equationxml = value; }
        }

        public string Path
        {
            get { return _path; }
            set { _path = value; }
        }


        public string Adj
        {
            get { return _adj; }
            set { _adj = value; }
        }


        public ShapeType Type
        {
            get { return _type; }
            set { _type = value; }
        }


        public List<ShapeElement> Elements
        {
            get { return _elements; }
        }

        internal AllCoreAttributes AllCoreAttributes
        {
            get
            {
                if (_core == null)
                    _core = new AllCoreAttributes();
                return _core;
            }
        }

        internal AllShapeAttributes AllShapeAttributes
        {
            get
            {
                if (_shape == null)
                    _shape = new AllShapeAttributes();
                return _shape;
            }
        }


        public string FillColor
        {
            get { return AllShapeAttributes.ShapeAttributes.FillColor; }
            set { AllShapeAttributes.FillColor = value; }
        }

        public Style Style
        {
            get { return AllCoreAttributes.CoreAttributes.Style; }
            set { AllCoreAttributes.CoreAttributes.Style = value; }
        }

        #region IOfficeXmlSerializable Members

        void IOfficeXmlSerializable.ReadXml(ReadContext context)
        {
            using (var c = context.Read(VmlConstants.VmlNamespace + xmlName))
            {
                AllCoreAttributes.ReadXml(c);
                AllShapeAttributes.ReadXml(c);
                var s = c.GetOptionalString("type");
                if (s != null)
                {
                    s = s.Replace(@"#", "");
                    var res = (ShapeTypeResolver) c.GetData<ShapeTypeResolver>();
                    Contract.Assert(res != null);
                    res.AddAction(s, st => _type = st);
                }

                Adj = c.GetOptionalString("adj");
                Path = c.GetOptionalString("path");
                EquationXml = c.GetOptionalString("equationxml");
                gfxdata = c.GetOptionalString(VmlConstants.OfficeNamespace + "gfxdata");
                c.WarnIf("ink");
                c.WarnIf("iscomment");
                var e = ShapeElement.ReadShapeElement(c);
                while (e != null)
                {
                    Elements.Add(e);
                    e = ShapeElement.ReadShapeElement(c);
                }
            }
        }

        void IOfficeXmlSerializable.WriteXml(WriteContext context)
        {
            using (var c = context.Write(VmlConstants.VmlNamespace + xmlName))
            {
                AllCoreAttributes.WriteXml(c);
                AllShapeAttributes.WriteXml(c);
                if (Type != null)
                    c.SetOptionalString("type", "#" + Type.Id);
                c.SetOptionalString("adj", Adj);
                c.SetOptionalString("path", Path);
                c.SetOptionalString("equationxml", EquationXml);
                c.SetOptionalString(VmlConstants.OfficeNamespace + "gfxdata", gfxdata);
                c.WarnIf("ink");
                c.WarnIf("iscomment");
                foreach (var e in Elements)
                    c.WriteElement(e);
            }
        }

        #endregion

        public T GetElement<T>() where T : ShapeElement
        {
            foreach (var e in Elements)
                if (e is T)
                    return (T) e;
            return default(T);
        }
    }
}